// 定义程序的命名空间   
var SHED = {};
SHED.tree = {};
SHED.data = {};
SHED.form = {};
SHED.grid = {};

// 加载Ext插件
SHED.plugins = {
    root: ['Window'],
    tree: ['DWRTreeLoader'],
    data: ['DWRProxy', 'DWRPageProxy', 'DWRReader', 'DWRPageReader', 'DWRStore'],
    form: ['DWRForm'],
    grid: ['CheckColumn', 'RadioSelectionModel', 'ListGrid', 'PagingToolbar', 'PageGrid']
};

for (var type in SHED.plugins) {
    var path = type == 'root' ? '' : type + '/';
    
    if (SHED.plugins[type] instanceof Array) {
        for (var index = 0; index < SHED.plugins[type].length; index++) {
            var name = SHED.plugins[type][index];
            document.write('<script type="text/javascript" src="scripts/ext-plugins/' + path + name + '.js"></script>');
        }
    }
}

// CM模块对象
SHED.module = function(main) {
    this.main = main;
    this.init();
    this.main.on('beforedestroy', function(o) {
        if (o.associatedComp && o.associatedComp instanceof Array) {
            for (var i = 0; i < o.associatedComp.length; i++) {
                Ext.destroy(o.associatedComp[i]);
            }
        }
    });
};
Ext.extend(SHED.module, Ext.util.Observable, {
    init: Ext.emptyFn
});

// 公用提示消息方法
SHED.msg = function(msg, title) {
    function createBox(t, s) {
        return ['<div class="msg">', '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>', '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc"><h3 style="float:left;">', t, '</h3><a class="qtip-close" onclick="SHED.closeMSG(1, event);"></a>', '<div style="clear:both;">', s, '</div>', '</div></div></div>', '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>', '</div>'].join('');
    }
    
    this.msgCt = Ext.DomHelper.insertFirst(document.body, {
        id: 'msg-div'
    }, true);
    
    title = title || '提示';
    this.msgCt.alignTo(document.body, 't-t');
    var m = Ext.DomHelper.append(this.msgCt, {
        html: createBox(title, msg)
    }, true);
    m.slideIn('t').pause(2).ghost('t', {
        remove: true
    });
};

// 关闭消息提示方法
SHED.closeMSG = function(o, e) {
    var evt = e || event;
    var obj = evt.srcElement || evt.target;
    var msgDiv = Ext.get(obj).up('.msg');
    if (msgDiv) {
        msgDiv.setStyle({
            display: 'none'
        });
    }
};

// 对象转换为字符串方法
SHED.toString = function(data, showLevels) {
    if (!showLevels) {
        showLevels = 2;
    }
    var opt = {
        escapeHtml: false,
        baseIndent: "",
        childIndent: "\u00A0\u00A0",
        lineTerminator: "\n",
        oneLineMaxItems: 5,
        shortStringMaxLength: 13,
        propertyNameMaxLength: 30
    };
    
    var skipDomProperties = {
        document: true,
        ownerDocument: true,
        all: true,
        parentElement: true,
        parentNode: true,
        offsetParent: true,
        children: true,
        firstChild: true,
        lastChild: true,
        previousSibling: true,
        nextSibling: true,
        innerHTML: true,
        outerHTML: true,
        innerText: true,
        outerText: true,
        textContent: true,
        attributes: true,
        style: true,
        currentStyle: true,
        runtimeStyle: true,
        parentTextEdit: true
    };
    
    var escapeHtml = function(original) {
        var div = document.createElement('div');
        var text = document.createTextNode(original);
        div.appendChild(text);
        return div.innerHTML;
    };
    
    var isArray = function(data) {
        return (data && data.join);
    };
    
    var isDate = function(data) {
        return (data && data.toUTCString) ? true : false;
    };
    
    var isObject = function(data) {
        return (data && typeof data == "object");
    };
    
    var detailedTypeOf = function(x) {
        var reply = typeof x;
        if (reply == "object") {
            reply = Object.prototype.toString.apply(x); // Returns "[object class]"
            reply = reply.substring(8, reply.length - 1); // Just get the class bit
        }
        return reply;
    };
    
    var isHTMLElement = function(ele, nodeName) {
        if (ele === null || typeof ele != "object" || !ele.nodeName) {
            return false;
        }
        if (nodeName) {
            var test = ele.nodeName.toLowerCase();
            if (typeof nodeName == "string") {
                return test == nodeName.toLowerCase();
            }
            if (isArray(nodeName)) {
                var match = false;
                for (var i = 0; i < nodeName.length && !match; i++) {
                    if (test == nodeName[i].toLowerCase()) {
                        match = true;
                    }
                }
                return match;
            }
            return false;
        }
        return true;
    };
    
    function recursive(data, showLevels, indentDepth, options) {
        var reply = "";
        try {
            // string
            if (typeof data == "string") {
                var str = data;
                if (showLevels === 0 && str.length > options.shortStringMaxLength) {
                    str = str.substring(0, options.shortStringMaxLength - 3) + "...";
                }
                if (options.escapeHtml) {
                    // Do the escape separately for every line as escapeHtml() on some 
                    // browsers (IE) will strip line breaks and we want to preserve them
                    var lines = str.split("\n");
                    for (var k = 0; k < lines.length; k++) {
                        lines[k] = escapeHtml(lines[k]);
                    }
                    str = lines.join("\n");
                }
                if (showLevels === 0) { // Short format
                    str = str.replace(/\n|\r|\t/g, function(ch) {
                        switch (ch) {
                            case "\n":
                                return "\\n";
                            case "\r":
                                return "";
                            case "\t":
                                return "\\t";
                        }
                    });
                } else { // Long format
                    str = str.replace(/\n|\r|\t/g, function(ch) {
                        switch (ch) {
                            case "\n":
                                return options.lineTerminator + indent(indentDepth + 1, options);
                            case "\r":
                                return "";
                            case "\t":
                                return "\\t";
                        }
                    });
                }
                reply = '"' + str + '"';
            } else if (typeof data == "function") { // function
                reply = "function";
            } else if (isArray(data)) { // Array
                if (showLevels === 0) { // Short format (don't show items)
                    if (data.length > 0) {
                        reply = "[...]";
                    } else {
                        reply = "[]";
                    }
                } else { // Long format (show items)
                    var strarr = [];
                    strarr.push("[");
                    var count = 0;
                    for (var i = 0; i < data.length; i++) {
                        if (!(i in data)) {
                            continue;
                        }
                        var itemvalue = data[i];
                        if (count > 0) {
                            strarr.push(", ");
                        }
                        if (showLevels == 1) { // One-line format
                            if (count == options.oneLineMaxItems) {
                                strarr.push("...");
                                break;
                            }
                        } else { // Multi-line format
                            strarr.push(options.lineTerminator + indent(indentDepth + 1, options));
                        }
                        if (i != count) {
                            strarr.push(i);
                            strarr.push(":");
                        }
                        strarr.push(recursive(itemvalue, showLevels - 1, indentDepth + 1, options));
                        count++;
                    }
                    if (showLevels > 1) {
                        strarr.push(options.lineTerminator + indent(indentDepth, options));
                    }
                    strarr.push("]");
                    reply = strarr.join("");
                }
            } else if (isObject(data) && !isDate(data)) { // Objects except Date
                if (showLevels === 0) { // Short format (don't show properties)
                    reply = detailedTypeOf(data);
                } else { // Long format (show properties)
                    var strarr2 = [];
                    if (detailedTypeOf(data) != "Object") {
                        strarr2.push(detailedTypeOf(data));
                        if (typeof data.valueOf() != "object") {
                            strarr2.push(":");
                            strarr2.push(recursive(data.valueOf(), 1, indentDepth, options));
                        }
                        strarr2.push(" ");
                    }
                    strarr2.push("{");
                    var isDomObject = isHTMLElement(data);
                    var count2 = 0;
                    for (var prop in data) {
                        var propvalue = data[prop];
                        if (isDomObject) {
                            if (!propvalue) {
                                continue;
                            }
                            if (typeof propvalue == "function") {
                                continue;
                            }
                            if (skipDomProperties[prop]) {
                                continue;
                            }
                            if (prop.toUpperCase() == prop) {
                                continue;
                            }
                        }
                        if (count2 > 0) {
                            strarr2.push(", ");
                        }
                        if (showLevels == 1) { // One-line format
                            if (count2 == options.oneLineMaxItems) {
                                strarr2.push("...");
                                break;
                            }
                        } else { // Multi-line format
                            strarr2.push(options.lineTerminator + indent(indentDepth + 1, options));
                        }
                        strarr2.push(prop.length > options.propertyNameMaxLength ? prop.substring(0, options.propertyNameMaxLength - 3) + "..." : prop);
                        strarr2.push(":");
                        strarr2.push(recursive(propvalue, showLevels - 1, indentDepth + 1, options));
                        count2++;
                    }
                    if (showLevels > 1 && count2 > 0) {
                        strarr2.push(options.lineTerminator + indent(indentDepth, options));
                    }
                    strarr2.push("}");
                    reply = strarr2.join("");
                }
            } else { // undefined, null, number, boolean, Date
                reply = "" + data;
            }
            
            return reply;
        } catch (err) {
            return (err.message ? err.message : "" + err);
        }
    }
    
    function indent(count, options) {
        var strarr = [];
        strarr.push(options.baseIndent);
        for (var i = 0; i < count; i++) {
            strarr.push(options.childIndent);
        }
        return strarr.join("");
    }
    
    return recursive(data, showLevels, 0, opt);
};

// CM主框架对象
SHED.app = function(north, south, west, center) {
    this.init(north, south, west, center);
};
Ext.extend(SHED.app, Ext.util.Observable, {
    init: function(north, south, west, center) {
        this.north = north;
        this.south = south;
        this.console = south;
        this.west = west;
        this.center = center;
        this.body = center;
        
        var viewport = new Ext.Viewport({
            layout: 'border',
            layoutConfig: {
                animate: false
            },
            items: [north, south, west, center]
        });
        
        this.loadMask = new Ext.LoadMask(this.body.body, {
            msg: "加载中，请稍候..."
        });
    },
    log: function(msg, level) {
        var title, now = new Date();
        switch (level) {
            case 1:
                title = '<font style="color: yellow;">警告</font>';
                break;
            case 2:
                title = '<font style="color: red;">错误</font>';
                break;
            case 3:
                title = '<font style="color: orange;">系统</font>';
                break;
            default:
                title = '<font style="color: green;">信息</font>';
                break;
        }
        var str = "<p>" + now.format('H:i:s') + " <b>[" + title + "]</b> " + SHED.toString(msg).replace(/\n/g, "<br />") + "</p>";
        this.console.body.insertHtml('afterBegin', str);
    }
});

// 调试DWR用方法
DWREngine.setErrorHandler(function(msg, ex) {
    if (msg.indexOf('未取得当前用户信息') > -1) {
        Ext.Msg.confirm('登录超时', msg + '<br />点击“是”将重新登录，“否”则停留在当前页面。', function(para) {
            if (para == 'yes') {
                location.reload();
            }
        });
    } else {
        Ext.Msg.alert('远程调用失败', msg);
        SHED.app.log(ex.replace('\n', '<br>'), 2);
    }
});
